﻿using NCD.Utility.Entity;
using OldDataSync.NewDomains;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OldDataSync
{
    class Program
    {
        private static readonly string connectionString = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;

        static void Main(string[] args)
        {
            try
            {
                SyncCustomer();
                var type = "0";
                do
                {
                    Console.WriteLine();
                    Console.WriteLine();
                    Console.WriteLine();
                    Console.WriteLine("您需要？");
                    Console.WriteLine("0:同步PA数据");
                    Console.WriteLine("1:同步VA数据");
                    Console.WriteLine("2:退出");
                    type = Console.ReadLine();
                    if (type == "0")
                    {
                        SyncPA();
                        Console.WriteLine("已完成");
                    }
                    if (type == "1")
                    {
                        SyncVA();
                        Console.WriteLine("已完成");
                    }
                } while (type != "2");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
            }
        }

        /// <summary>
        /// 同步用户
        /// </summary>
        static void SyncCustomer()
        {
            var dBContext = new DBContext(connectionString);
            var newCustomers = dBContext.CustomerDB.GetList().Select(c => c.IDNumber).ToList();
            var oldCustomer = dBContext.OldCustomerDB.GetList();
            var list = oldCustomer.Where(c => !newCustomers.Contains(c.NUI_IdentityNumber)).Select(c => new Customer
            {
                IDNumber = c.NUI_IdentityNumber,
                Name = c.NUI_Name,
                Phone = long.TryParse(c.NUI_Phone, out var phone) ? phone : 0,
            }).ToList();
            if (list.Count > 0)
                dBContext.CustomerDB.InsertRange(list.ToArray());
        }

        /// <summary>
        /// 同步PA
        /// </summary>
        static void SyncPA()
        {
            var context = new DBContext(connectionString);
            var oldPARecords = context.OldPARecordsDB.GetList();
            var tables = new HashSet<string>();
            var customers = context.CustomerDB.GetList();
            var qs = context.PAQuestionDB.GetList();
            var answers = context.PAAnswerDB.GetList();
            context.NewDb.BeginTran();
            var count = oldPARecords.Count;
            var dcnSelectioins = new Dictionary<int, List<BaseSelections>>();
            try
            {
                foreach (var record in oldPARecords)
                {
                    var year = record.NP_CreateDate.Year;
                    var name = "PASelections_" + year;
                    context.NewDb.MappingTables.Add(nameof(PASelections), name);
                    if (!tables.Contains(name) && !context.NewDb.DbMaintenance.IsAnyTable(name))
                        context.NewDb.CodeFirst.InitTables<PASelections>();
                    tables.Add(name);
                    if (!dcnSelectioins.ContainsKey(year))
                        dcnSelectioins.Add(year, context.OldSelectionsDB.AsQueryable().AS(record.NP_Table).ToList());
                    var selections = dcnSelectioins[year].Where(c => c.NS_ParentID == record.NP_ID).ToList();
                    var order = 0;
                    var newSelections = selections.Select(c => new PASelections
                    {
                        Category = c.NS_Key,
                        NAID = answers.Find(d => d.Name == c.NS_NAName).Id,
                        NAName = c.NS_NAName,
                        NQID = qs.Find(d => d.Name == c.NS_NQName)?.Id ?? qs.Find(d => d.Name.StartsWith(c.NS_NQName))?.Id ?? qs.Find(d => c.NS_NQName.StartsWith(d.Name)).Id,
                        NQName = c.NS_NQName,
                        Order = order += 5,
                        Score = c.NS_Score,
                        Value = qs.Find(d => d.Name == c.NS_NQName)?.Value
                    }).ToList();
                    var id = context.PARecordsDB.InsertReturnIdentity(new PARecords
                    {
                        BST = record.NP_BST,
                        CustomerId = customers.Find(c => c.IDNumber == record.NP_IdentityNumber).Id,
                        IDNumber = record.NP_IdentityNumber,
                        PATable = name,
                        PHFMGP12 = record.NP_PHFMGP12,
                        PHFMGP13_25 = record.NP_PHFMGP13_25,
                        PHFMHP26_39 = record.NP_PHFMHP26_39,
                        PHFMHP40_50 = record.NP_PHFMHP40_50,
                        RiskLevel = record.NP_KPI,
                        CreateDate = record.NP_CreateDate,
                    });
                    newSelections.ForEach(c => c.ParentId = id);
                    context.NewDb.Insertable<PASelections>(newSelections).AS(name).ExecuteCommand();
                }
            }
            catch (Exception ex)
            {
                context.NewDb.RollbackTran();
                throw ex;
            }
            context.NewDb.CommitTran();
        }

        /// <summary>
        /// 同步VA
        /// </summary>
        static void SyncVA()
        {
            var context = new DBContext(connectionString);
            var oldPARecords = context.OldVARecordsDB.GetList().OrderBy(c => c.NV_CreateDate).ToList();
            var tables = new HashSet<string>();
            var customers = context.CustomerDB.GetList();
            var qs = context.VAQuestionDB.GetList();
            var answers = context.VAAnswerDB.GetList();
            var lthrs = context.LTHRDB.GetList();
            var count = oldPARecords.Count;
            var dcnSelectioins = new Dictionary<int, List<BaseSelections>>();
            var maxId = context.VARecordsDB.AsQueryable().Max(c => c.Id);
            var dcnValues = new Dictionary<int, List<NCD_LTHRValues>>();
            var years = oldPARecords.Select(c => c.NV_CreateDate.Year).Distinct().ToList();
            try
            {
                years.ForEach(year =>
                {
                    var list = new List<VASelections>();
                    var values = new List<LTHRValues>();
                    var name = "VASelections_" + year;
                    var lthrName = "LTHRValues_" + year;
                    context.NewDb.MappingTables.Add(nameof(VASelections), name);
                    context.NewDb.MappingTables.Add(nameof(LTHRValues), lthrName);
                    if (!tables.Contains(name) && !context.NewDb.DbMaintenance.IsAnyTable(name))
                        context.NewDb.CodeFirst.InitTables<VASelections>();
                    tables.Add(name);
                    if (!tables.Contains(lthrName) && !context.NewDb.DbMaintenance.IsAnyTable(lthrName))
                        context.NewDb.CodeFirst.InitTables<LTHRValues>();
                    tables.Add(lthrName);

                    foreach (var record in oldPARecords.Where(c => c.NV_CreateDate.Year == year).ToArray())
                    {
                        if (!dcnSelectioins.ContainsKey(year))
                        {
                            dcnSelectioins.Add(year, context.OldSelectionsDB.AsQueryable().AS(record.NV_Table).ToList());
                            dcnValues.Add(year, context.OldLTHRValuesDB.AsQueryable().AS(record.NV_LTHRTable).ToList());
                        }
                        var selections = dcnSelectioins[year].Where(c => c.NS_ParentID == record.NV_ID).ToList();
                        var newSelections = selections.Select(c => new VASelections
                        {
                            Code = c.NS_Code,
                            NAID = answers.Find(d => d.Name == c.NS_NAName)?.Id ?? 0,
                            NAName = c.NS_NAName,
                            NQID = qs.Find(d => d.Name == c.NS_NQName)?.Id ?? 0,
                            NQName = c.NS_NQName,
                            Score = c.NS_Score,
                        }).ToList();
                        var lthrValues = dcnValues[year].Where(c => c.NLV_ParentID == record.NV_ID).ToList().Select(c => new LTHRValues
                        {
                            Category = c.NLV_Category,
                            Code = c.NLV_Code,
                            CreateDate = record.NV_CreateDate,
                            NLID = lthrs.Find(d => d.Code == c.NLV_Code)?.Id ?? 0,
                            RiskLevel = c.NLV_RiskLevel,
                            Score = c.NLV_Score,
                            Value = c.NLV_Value,
                        }).ToList();
                        var id = context.VARecordsDB.InsertReturnIdentity(new VARecords
                        {
                            CustomerId = customers.Find(c => c.IDNumber == record.NV_IdentityNumber).Id,
                            IDNumber = record.NV_IdentityNumber,
                            LTHRTable = lthrName,
                            Finish = record.NV_Finish,
                            PECount = record.NV_PECount,
                            PEID = record.NV_PEID,
                            Score = record.NV_Base + record.NV_MTHR + record.NV_STHR,
                            VATable = name,
                            CreateDate = record.NV_CreateDate
                        });
                        newSelections.ForEach(c => c.ParentID = id);
                        lthrValues.ForEach(c => c.ParentID = id);
                        list.AddRange(newSelections);
                        values.AddRange(lthrValues);
                    }
                    context.VASelectionsDB.InsertRange(list);
                    context.LTHRValuesDB.InsertRange(values);
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
